"""Keep the UI functioning within the same thread.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA


Internal (Infernal ??) package holding decorators to keep the UI
running correctly, This package deals with the threading model of the
simulation, managing the locks placed on threads.

There should be no need for the user to call any of these methods from
a simulation, if so BadThings(TM) are likely to happen.
"""


__author__ = 'John Perks'

import threading, pdb

import wx

_pauseLock = threading.Event()
_simRunning = False


def Check():
    """ Check whether the simulation is running.  If Not raise a SimulationCancelled exception.
    otherwise place the pauseLock attribute into wait status"""
    if not _simRunning:
        raise SimulationCancelled
    _pauseLock.wait()

class SimulationCancelled(Exception):
    pass

SimulationCanceled = SimulationCancelled


def PauseSim():
    """Pauses the simulation. Releases the pauseLock effectively pausing the simulation"""
    _pauseLock.clear()


def SimPaused():
    """Returns whether the simulation is paused. This will return True if and only if the Simulation is both
     Running (Started) and Paused."""
    return _simRunning and not _pauseLock.isSet()

def ResumeSim():
    """Restarts the simulation after it has been paused"""
    _pauseLock.set()


def CancelSim():
    """Cancels running of the simulation.  This will first resume the simulation to remove any Pause flags.
    then stop the  execution of the simulation"""
    ResumeSim()
    global _simRunning
    if not _simRunning:
        return
    _simRunning = False

def RestartSim():
    """ Restarts the simulation.
    This will first Cancel a simulation if it is currently running. Then start the simulation again"""
    global _simRunning
    CancelSim()
    _simRunning = True
    ResumeSim()

def SimRunning():
    """Returns whether the simulation is running on not.
    Will Return True if the simulation is Running and not paused"""
    return _simRunning and not SimPaused()


